using Common.Commands;
using Common.Commands.AccountCommands;
using Core.Domain.Model;
using Core.Infrastructure.CustomExceptions;
using Dto.ApiResponses.AccountResponses;
using Sanelib.Common.Helpers;
using Sanelib.DataOperation;

namespace Core.Processors.AccountProcessors
{

    public class AddAccountProcessor : ICommandProcessor<AddAccount>
    {
        private const string UserWithSameUsernameExceptionMssg =
          "A user with the same username already exists in the system.";

        private readonly IRepository<Account> _accountRepository;

        public AddAccountProcessor(IRepository<Account> accountRepository)
        {
            _accountRepository = accountRepository;
        }

        public dynamic Process(AddAccount command)
        {
            EnsureUniqueness(command);

            var account = new Account
            {
                Id = command.Id,
                Name = command.Name,
                AccountType = command.AccountType,
                AccountNumber = command.AccountNumber,
                Industry = command.Industry,
                BillingStreet = command.BillingStreet,
                BillingCity = command.BillingCity,
                BillingState = command.BillingState,
                BillingPostalCode = command.BillingPostalCode,
                BillingCountry = command.BillingCountry,
                BillingLatitude = 0,
                BillingLongitude = 0,
                ShippingStreet = command.ShippingStreet,
                ShippingCity = command.ShippingCity,
                ShippingState = command.ShippingState,
                ShippingPostalCode = command.ShippingPostalCode,
                ShippingCountry = command.ShippingCountry,
                ShippingLatitude = 0,
                ShippingLongitude = 0,
                Phone = command.Phone,
                Mobile = command.Mobile,
                Fax = command.Fax,
                Website = command.Website,
                Email = command.Email,
                Description = command.Description,
                ImageData = command.ImageData,
                CreatedBy = command.UserId
            };
            _accountRepository.Add(account);

            return new AccountResponse
            {
                Id = command.Id,
                Name = command.Name,
                AccountNumber = command.AccountNumber,
                Description = command.Description,
                ImageData = command.ImageData,
            };
        }

        private void EnsureUniqueness(AddAccount command)
        {
            var userWithSameUsername = _accountRepository.GetByKey(Property.Of<Account>(entity => entity.Name), command.Name);

            if (userWithSameUsername != null)
            {
                throw new DomainProcessException(UserWithSameUsernameExceptionMssg);
            }
        }
    }
}
